package com.ant.storage.service.impl;

import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultPage;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.InventoryCheckMapper;
import com.ant.storage.pojo.Inventory;
import com.ant.storage.pojo.InventoryCheck;
import com.ant.storage.pojo.InventoryCheckCommodity;
import com.ant.storage.service.ICityService;
import com.ant.storage.service.IInventoryCheckService;
import com.ant.storage.service.IInventoryService;
import com.ant.storage.utils.NullInspectUtil;
import com.ant.storage.common.PageRecv;
import com.ant.storage.common.ResultVo;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class InventoryCheckServiceImpl extends ServiceImpl<InventoryCheckMapper,InventoryCheck> implements IInventoryCheckService {

    @Autowired(required = false)
    InventoryCheckMapper inventoryCheckMapper;

    @Autowired
    ICityService cityService;

    @Autowired
    IInventoryService inventoryService;

    @Override
    public InventoryCheck editVerification(@Valid InventoryCheck inventoryCheck,BindingResult bindingResult){
        this.verification(inventoryCheck,bindingResult);
        inventoryCheck.setInventory_check_type(1);
        return inventoryCheck;
    }

    @Override
    public InventoryCheck confirmVerification(@Valid InventoryCheck inventoryCheck, BindingResult bindingResult) {
        this.verification(inventoryCheck,bindingResult);
        inventoryCheck.setInventory_check_type(2);
        return inventoryCheck;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo updateInventoryCheckEdit(InventoryCheck inventoryCheck) {
        if(inventoryCheck.getInventory_check_id() == null||inventoryCheck.getInventory_check_id()<= 0){
            throw new AntException(ResultCode.INVENTORYCHECK_ID_ERROR);
        }
        if(inventoryCheck.getList() == null){
            throw new AntException(ResultCode.GOOD_NULL_ERROR);
        }
        //删除中间表数据
        inventoryCheckMapper.deleteInventoryCheckCommodity(inventoryCheck.getInventory_check_id());
        this.addInventoryCheckCommodity(inventoryCheck);
        return ResultVo.success("ok");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo inventoryCheckEditConfirm(InventoryCheck inventoryCheck) {
        this.updateInventoryCheckEdit(inventoryCheck);
        //更新状态
        UpdateWrapper<InventoryCheck> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("inventory_check_id",inventoryCheck.getInventory_check_id());
        inventoryCheck.setInventory_check_type(2);
        this.update(inventoryCheck,updateWrapper);
        //更新库存信息
        for(InventoryCheckCommodity inventoryCheckCommodity:inventoryCheck.getList()){
            this.updateInventory(inventoryCheckCommodity.getCommodity().getCommodityId(),inventoryCheckCommodity.getCheck_quantity(),inventoryCheckCommodity.getWarehouse().getId());
        }
        return ResultVo.success("ok");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo addInventoryCheckEdit(InventoryCheck inventoryCheck){
        this.save(inventoryCheck);
        this.addInventoryCheckCommodity(inventoryCheck);
        return ResultVo.success("ok");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo addInventoryCheckConfirm(InventoryCheck inventoryCheck) {
        this.save(inventoryCheck);
        this.addInventoryCheckCommodity(inventoryCheck);
        for(InventoryCheckCommodity inventoryCheckCommodity:inventoryCheck.getList()){
            this.updateInventory(inventoryCheckCommodity.getCommodity().getCommodityId(),inventoryCheckCommodity.getCheck_quantity(),inventoryCheckCommodity.getWarehouse().getId());
        }
        return ResultVo.success("ok");
    }

    @Override
    public ResultPage queryInventoryCheck(PageRecv<InventoryCheck> pageRecv) {
        Map map = new HashMap<>();
        if (!(pageRecv.getData()==null)){
            map = NullInspectUtil.ClassChangeMapNotNull(pageRecv.getData());
        }
        Integer page = (pageRecv.getCurrentPage()-1)*pageRecv.getPageSize();
        Integer limit = pageRecv.getCurrentPage()*pageRecv.getPageSize();
        List<InventoryCheck> list = inventoryCheckMapper.queryInventoryCheck(page,limit,map);
        //城市查询并添加
//        for(InventoryCheck inventoryCheck:list){
//            inventoryCheck.getCity().setName(cityService.idQuery(inventoryCheck.getCity_id()));
//            inventoryCheck.getDept().setName(cityService.idQuery(inventoryCheck.getDept_id()));
//        }
        Integer count = inventoryCheckMapper.countInventoryCheck(map);
        return ResultPage.success("ok", list, count);
    }

    /**
     * 数据验证以及添加时间
     * @param inventoryCheck
     * @param bindingResult
     */
    private void verification(@Valid InventoryCheck inventoryCheck, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            throw new AntException(20001,bindingResult.getFieldError().getDefaultMessage());
        }
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        inventoryCheck.setInventory_check_time(simpleDateFormat.format(date));
    }

    /**
     * 中间表添加
     * @param inventoryCheck
     */
    @Transactional(rollbackFor = Exception.class)
    void addInventoryCheckCommodity(InventoryCheck inventoryCheck){
        for(InventoryCheckCommodity inventoryCheckCommodity:inventoryCheck.getList()){
            if(Double.parseDouble(inventoryCheckCommodity.getCheck_quantity())<0){
                throw new AntException(ResultCode.INVENTORY_QUANTITY_ERROR);
            }
            inventoryCheckMapper.addInventoryCheckCommodity(inventoryCheck.getInventory_check_id(),inventoryCheckCommodity);
        }
    }

    /**
     * 库存更新
     * @param commodity_id
     * @param check_quantity
     * @param warehouse_id
     */
    @Transactional(rollbackFor = Exception.class)
    void updateInventory(Integer commodity_id,String check_quantity,Integer warehouse_id){
        UpdateWrapper<Inventory>updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("warehouse_id",warehouse_id).eq("commodity_id",commodity_id);
        Inventory inventory = new Inventory();
        inventory.setGoodsAmount(new BigDecimal(check_quantity).setScale(2,BigDecimal.ROUND_HALF_UP));
        inventoryService.update(inventory,updateWrapper);
    }
}
